home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / SciAn / src / ScianObjWindows.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  40KB  |  1,878 lines

  1. /*ScianObjWindows.c
  2.   Object window stuff
  3.   Eric Pepke
  4.   March 28, 1990
  5. */
  6. #include "Scian.h"
  7. #include "ScianTypes.h"
  8. #include "ScianLists.h"
  9. #include "ScianWindows.h"
  10. #include "ScianColors.h"
  11. #include "ScianIDs.h"
  12. #include "ScianObjWindows.h"
  13. #include "ScianErrors.h"
  14. #include "ScianDraw.h"
  15. #include "ScianControls.h"
  16. #include "ScianArrays.h"
  17. #include "ScianScripts.h"
  18. #include "ScianVisWindows.h"
  19. #include "ScianDialogs.h"
  20. #include "ScianIcons.h"
  21. #include "ScianEvents.h"
  22. #include "ScianStyle.h"
  23. #include "ScianObjFunctions.h"
  24. #include "ScianPictures.h"
  25. #include "ScianButtons.h"
  26. #include "ScianTitleBoxes.h"
  27. #include "ScianTextBoxes.h"
  28. #include "ScianSliders.h"
  29.  
  30. #ifdef PROTO
  31. void ReshapeList(ThingListPtr, int, int, int, int, int, int, int, int);
  32. #else
  33. void ReshapeList();
  34. #endif
  35.  
  36. Bool invalidFound = false;
  37. int pauseDrawing = 0;
  38. char tempStr[TEMPSTRSIZE + 1];
  39. ObjPtr objWindowClass;            /*Object window class*/
  40. ObjPtr dragBuffer = NULLOBJ;        /*Objects held*/
  41. Bool showWindows = true;        /*Show new opened windows*/
  42.  
  43. ObjPtr NewControlWindow(object)
  44. ObjPtr object;
  45. /*Opens a new control window for object*/
  46. {
  47.     FuncTyp newCtlWindow;
  48.     ObjPtr retVal;
  49.     ObjPtr repObj, name, repName = NULLOBJ;
  50.     char windowName[255];
  51.  
  52.     if (IsIcon(object))
  53.     {
  54.     /*It's an icon, use its REPOBJ.  Do nothing if it has none.*/
  55.     object = GetVar(object, REPOBJ);
  56.     if (!object)
  57.     {
  58.         return ObjFalse;
  59.     }
  60.     }
  61.  
  62.     strcpy(windowName, "");
  63.  
  64.     MakeVar(object, NAME);
  65.     name = GetVar(object, NAME);
  66.     if (name)
  67.     {
  68.     if (repName)
  69.     {
  70.         strcat(windowName, " ");
  71.     }
  72.     strcat(windowName, GetString(name));
  73.     }
  74.  
  75.     newCtlWindow = GetMethod(object, NEWCTLWINDOW);
  76.     if (newCtlWindow)
  77.     {
  78.     PauseDrawing(true);
  79.     showWindows = showControlPanels;
  80.     retVal = (*newCtlWindow)(object, windowName);
  81.     showWindows = true;
  82.     PauseDrawing(false);
  83.     }
  84.     else
  85.     {
  86.     retVal = NULLOBJ;
  87.     }
  88.     return retVal;
  89. }
  90.  
  91. void SetEndpoints(object, x1, y1, x2, y2)
  92. ObjPtr object;
  93. int x1, y1, x2, y2;
  94. /*Sets the endpoints of an object*/
  95. {
  96.     int l, r, b, t;
  97.     ObjPtr var;
  98.     real loc[2];
  99.  
  100.     l = MIN(x1, x2) - HANDLESIZE / 2;
  101.     r = MAX(x1, x2) + HANDLESIZE / 2;
  102.     b = MIN(y1, y2) - HANDLESIZE / 2;
  103.     t = MAX(y1, y2) + HANDLESIZE / 2;
  104.     Set2DIntBounds(object, l, r, b, t);
  105.  
  106.     var = NewRealArray(1, 2L);
  107.     loc[0] = x1;
  108.     loc[1] = y1;
  109.     CArray2Array(var, loc);
  110.     SetVar(object, STARTPOINT, var);
  111.  
  112.     var = NewRealArray(1, 2L);
  113.     loc[0] = x2;
  114.     loc[1] = y2;
  115.     CArray2Array(var, loc);
  116.     SetVar(object, ENDPOINT, var);
  117. }
  118.  
  119. Bool Get2DIntBounds(object, l, r, b, t)
  120. ObjPtr object;
  121. int *l, *r, *b, *t;
  122. /*Gets the 2D integer bounds of a screen object*/
  123. {
  124.     ObjPtr boundsArray;
  125.     boundsArray = GetFixedArrayVar("Get2DIntBounds", object, BOUNDS, 1, 4L);
  126.     if (boundsArray)
  127.     {
  128.     real temp[4];
  129.     Array2CArray(temp, boundsArray);
  130.     *l = temp[0];
  131.     *r = temp[1];
  132.     *b = temp[2];
  133.     *t = temp[3];
  134.     return true;
  135.     }
  136.     else
  137.     {
  138.     return false;
  139.     }
  140. }
  141.  
  142. Bool Set2DIntBounds(object, l, r, b, t)
  143. ObjPtr object;
  144. int l, r, b, t;
  145. /*Sets the 2D integer bounds of a screen object to l, r, b, t*/
  146. {
  147.     ObjPtr boundsArray;
  148.     boundsArray = NewRealArray(1, 4L);
  149.     if (boundsArray)
  150.     {
  151.     real temp[4];
  152.     temp[0] = l;
  153.     temp[1] = r;
  154.     temp[2] = b;
  155.     temp[3] = t;
  156.     CArray2Array(boundsArray, temp);
  157.     SetVar(object, BOUNDS, boundsArray);
  158.     return true;
  159.     }
  160.     else
  161.     {
  162.     return false;
  163.     }
  164. }
  165.  
  166. void ForAllObjects(obj, routine)
  167. ObjPtr obj;
  168. FuncTyp routine;
  169. /*Performs routine on all selected objects in win*/
  170. {
  171.     ObjPtr contents;
  172.     FuncTyp method;
  173.  
  174.     method = GetMethod(obj, FORALLOBJECTS);
  175.     if (method)
  176.     {
  177.     (*method)(obj, routine);
  178.     }
  179. }
  180.  
  181. static ObjPtr CloseObjWindow(theInfo)
  182. WinInfoPtr theInfo;
  183. /*Closes obj window theInfo*/
  184. {  
  185.     return ObjTrue;
  186. }
  187.  
  188. #ifdef GODLIKE
  189. static ObjPtr DrawBounds(stuff)
  190. ObjPtr stuff;
  191. /*Draws the bounds of stuff*/
  192. {
  193.     ThingListPtr runner;
  194.     ObjPtr bounds, contents;
  195.     if (IsList(stuff))
  196.     {
  197.     runner = LISTOF(stuff);
  198.     while (runner)
  199.     {
  200.         DrawBounds(runner -> thing);
  201.         runner = runner -> next;
  202.     }
  203.     }
  204.     else
  205.     {
  206.     contents = GetVar(stuff, CONTENTS);
  207.     if (contents)
  208.     {
  209.         DrawBounds(contents);
  210.     }
  211.     bounds = GetVar(stuff, BOUNDS);
  212.     if (bounds)
  213.     {
  214.         int l, r, b, t;
  215.         Get2DIntBounds(stuff, &l, &r, &b, &t);
  216.         FrameUIRect(l, r, b, t, UIWHITE);
  217.     }
  218.     }
  219. }
  220.  
  221. static ObjPtr DrawSoftBounds(stuff)
  222. ObjPtr stuff;
  223. /*Draws the soft bounds of stuff*/
  224. {
  225.     ThingListPtr runner;
  226.     ObjPtr bounds, contents;
  227.     if (IsList(stuff))
  228.     {
  229.     runner = LISTOF(stuff);
  230.     while (runner)
  231.     {
  232.         DrawSoftBounds(runner -> thing);
  233.         runner = runner -> next;
  234.     }
  235.     }
  236.     else
  237.     {
  238.     contents = GetVar(stuff, CONTENTS);
  239.     if (contents)
  240.     {
  241.         DrawSoftBounds(contents);
  242.     }
  243.     bounds = GetVar(stuff, BOUNDS);
  244.     if (bounds)
  245.     {
  246.         int l, r, b, t;
  247.         ObjPtr softBounds;
  248.         Get2DIntBounds(stuff, &l, &r, &b, &t);
  249.         softBounds = GetVar(stuff, INNERSOFTMARGIN);
  250.         if (!softBounds)
  251.         {
  252.             FrameUIRect(l + MINORBORDER, r - MINORBORDER, b + MINORBORDER, t - MINORBORDER, UIRED);
  253.         }
  254.         softBounds = GetVar(stuff, OUTERSOFTMARGIN);
  255.         if (!softBounds)
  256.         {
  257.             FrameUIRect(l - MINORBORDER, r + MINORBORDER, b - MINORBORDER, t + MINORBORDER, UIRED);
  258.         }
  259.     }
  260.     }
  261. }
  262.  
  263. static void SaveSubTemplate(stuff, file)
  264. ObjPtr stuff;
  265. FILE *file;
  266. /*Saves a subtemplate for stuff and its contents into file*/
  267. {
  268.     ThingListPtr runner;
  269.     ObjPtr bounds, contents, name;
  270.     if (IsList(stuff))
  271.     {
  272.     runner = LISTOF(stuff);
  273.     while (runner)
  274.     {
  275.         SaveSubTemplate(runner -> thing, file);
  276.         runner = runner -> next;
  277.     }
  278.     }
  279.     else
  280.     {
  281.     contents = GetVar(stuff, CONTENTS);
  282.     if (contents)
  283.     {
  284.         SaveSubTemplate(contents, file);
  285.     }
  286.     bounds = GetVar(stuff, BOUNDS);
  287.     if (bounds)
  288.     {
  289.         int l, r, b, t;
  290.         Get2DIntBounds(stuff, &l, &r, &b, &t);
  291.         name = GetVar(stuff, NAME);
  292.         if (name)
  293.         {
  294.         fprintf(file, "\t{\"%s\", %d, %d, %d, %d},\n",
  295.             GetString(name), l, r, b, t);
  296.         }
  297.     }
  298.     }
  299. }
  300.  
  301. static ObjPtr SaveTemplateReally(owner, reply)
  302. ObjPtr owner;
  303. char *reply;
  304. /*Really saves a template named reply*/
  305. {
  306.     FILE *file;
  307.     char fileName[200];
  308.     ObjPtr contents;
  309.     contents = GetVar(GetVar(owner, OWNERWINDOW), CONTENTS);
  310.  
  311.     sprintf(fileName, "%s.tpl", reply);
  312.     file = fopen(fileName, "w");
  313.     if (file)
  314.     {
  315.         fprintf(file, "Template %sTemplate[] =\n    {\n", reply);
  316.         SaveSubTemplate(contents, file);
  317.         fprintf(file, "\t{\"\", 0, 0, 0, 0}\n");
  318.         fprintf(file, "    };\n\n");
  319.         fclose(file);
  320.     }
  321. }
  322.  
  323. void DoSaveTemplate()
  324. /*Saves a template for the current window*/
  325. {
  326.     if (selWinInfo)
  327.     {
  328.     char *s;
  329.     WinInfoPtr curWindow, alertWindow;
  330.  
  331.     /*Figure out the name for the template*/
  332.     strcpy(tempStr, selWinInfo -> winTitle);
  333.     s = tempStr;
  334.  
  335.     while (*s)
  336.     {
  337.         if (*s == ' ') *s = '_';
  338.         ++s;
  339.     }
  340.     curWindow = selWinInfo;
  341.     alertWindow = AskUser((WinInfoPtr) selWinInfo,
  342.         "Enter template name:", (FuncTyp) SaveTemplateReally, tempStr);
  343.     SetVar((ObjPtr) alertWindow, OWNERWINDOW, (ObjPtr) curWindow);
  344.     }
  345. }
  346.  
  347. static ObjPtr AddObjToWindow(object, dialog)
  348. ObjPtr object;
  349. ObjPtr dialog;
  350. {
  351.     ObjPtr contents, panel;
  352.     contents = GetVar(GetVar(dialog, OWNERWINDOW), CONTENTS);
  353.  
  354.     panel = LISTOF(contents) -> thing;
  355.     if (panel)
  356.     {
  357.     contents = GetVar(panel, CONTENTS);
  358.     PrefixList(contents, object);
  359.     SetVar(object, PARENT, panel);
  360.     ImInvalid(object);
  361.     }
  362. }
  363.  
  364. static ObjPtr NewScreenSlider(dialog, name)
  365. ObjPtr dialog;
  366. char *name;
  367. /*Makes a new slider*/
  368. {
  369.     ObjPtr object;
  370.  
  371.     object = NewSlider(10, 10 + SLIDERWIDTH, 10, 100, PLAIN, name);
  372.     AddObjToWindow(object, dialog);
  373. }
  374.  
  375. static ObjPtr NewScreenScaleSlider(dialog, name)
  376. ObjPtr dialog;
  377. char *name;
  378. /*Makes a new slider*/
  379. {
  380.     ObjPtr object;
  381.  
  382.     object = NewSlider(10, 10 + SLIDERWIDTH, 10, 100, SCALE, name);
  383.     AddObjToWindow(object, dialog);
  384. }
  385.  
  386. static ObjPtr NewScreenTitleBox(dialog, name)
  387. ObjPtr dialog;
  388. char *name;
  389. /*Makes a new title box*/
  390. {
  391.     ObjPtr object;
  392.  
  393.     object = NewTitleBox(10, 100, 10, 70, name);
  394.     AddObjToWindow(object, dialog);
  395. }
  396.  
  397. static ObjPtr NewScreenRadioButton(dialog, name)
  398. ObjPtr dialog;
  399. char *name;
  400. /*Makes a new radio button*/
  401. {
  402.     ObjPtr object;
  403.  
  404.     object = NewRadioButton(10, 100, 10, 10 + CHECKBOXHEIGHT, name);
  405.     AddObjToWindow(object, dialog);
  406. }
  407.  
  408. static ObjPtr NewScreenPlainButton(dialog, name)
  409. ObjPtr dialog;
  410. char *name;
  411. /*Makes a new plain button*/
  412. {
  413.     ObjPtr object;
  414.  
  415.     object = NewButton(10, 100, 10, 10 + BUTTONHEIGHT, name);
  416.     AddObjToWindow(object, dialog);
  417. }
  418.  
  419. static ObjPtr NewScreenShortButton(dialog, name)
  420. ObjPtr dialog;
  421. char *name;
  422. /*Makes a new plain button*/
  423. {
  424.     ObjPtr object;
  425.  
  426.     object = NewButton(10, 100, 10, 10 + SHORTBUTTONHEIGHT, name);
  427.     AddObjToWindow(object, dialog);
  428. }
  429.  
  430. static ObjPtr NewScreenCheckBox(dialog, name)
  431. ObjPtr dialog;
  432. char *name;
  433. /*Makes a new check box*/
  434. {
  435.     ObjPtr object;
  436.  
  437.     object = NewCheckBox(10, 100, 10, 10 + CHECKBOXHEIGHT, name, false);
  438.     AddObjToWindow(object, dialog);
  439. }
  440.  
  441. static ObjPtr NewScreenTextBox(dialog, name)
  442. ObjPtr dialog;
  443. char *name;
  444. /*Makes a new text box*/
  445. {
  446.     ObjPtr object;
  447.  
  448.     object = NewTextBox(10, 100, 10, 10 + TEXTBOXHEIGHT, 0, name, name);
  449.     AddObjToWindow(object, dialog);
  450. }
  451.  
  452. static ObjPtr NewScreenEditableTextBox(dialog, name)
  453. ObjPtr dialog;
  454. char *name;
  455. /*Makes a new text box*/
  456. {
  457.     ObjPtr object;
  458.  
  459.     object = NewTextBox(10, 100, 10, 10 + EDITBOXHEIGHT, EDITABLE + WITH_PIT + ONE_LINE, name, name);
  460.     AddObjToWindow(object, dialog);
  461. }
  462.  
  463. void DoNewScreenSlider()
  464. /*Makes a new slider in the current window*/
  465. {
  466.     if (selWinInfo)
  467.     {
  468.     WinInfoPtr curWindow, alertWindow;
  469.  
  470.     curWindow = selWinInfo;
  471.     alertWindow = AskUser((WinInfoPtr) selWinInfo,
  472.         "Please name the new object:", (FuncTyp) NewScreenSlider, "");
  473.     SetVar((ObjPtr) alertWindow, OWNERWINDOW, (ObjPtr) curWindow);
  474.     }
  475. }
  476.  
  477. void DoNewScreenScaleSlider()
  478. /*Makes a new scale slider in the current window*/
  479. {
  480.     if (selWinInfo)
  481.     {
  482.     WinInfoPtr curWindow, alertWindow;
  483.  
  484.     curWindow = selWinInfo;
  485.     alertWindow = AskUser((WinInfoPtr) selWinInfo,
  486.         "Please name the new object:", (FuncTyp) NewScreenScaleSlider, "");
  487.     SetVar((ObjPtr) alertWindow, OWNERWINDOW, (ObjPtr) curWindow);
  488.     }
  489. }
  490.  
  491. void DoNewScreenTitleBox()
  492. /*Makes a new title box in the current window*/
  493. {
  494.     if (selWinInfo)
  495.     {
  496.     WinInfoPtr curWindow, alertWindow;
  497.  
  498.     curWindow = selWinInfo;
  499.     alertWindow = AskUser((WinInfoPtr) selWinInfo,
  500.         "Please name the new object:", (FuncTyp) NewScreenTitleBox, "");
  501.     SetVar((ObjPtr) alertWindow, OWNERWINDOW, (ObjPtr) curWindow);
  502.     }
  503. }
  504.  
  505. void DoNewScreenRadioButton()
  506. /*Makes a new radio button in the current window*/
  507. {
  508.     if (selWinInfo)
  509.     {
  510.     WinInfoPtr curWindow, alertWindow;
  511.  
  512.     curWindow = selWinInfo;
  513.     alertWindow = AskUser((WinInfoPtr) selWinInfo,
  514.         "Please name the new object:", (FuncTyp) NewScreenRadioButton, "");
  515.     SetVar((ObjPtr) alertWindow, OWNERWINDOW, (ObjPtr) curWindow);
  516.     }
  517. }
  518.  
  519. void DoNewScreenPlainButton()
  520. /*Makes a new plain button in the current window*/
  521. {
  522.     if (selWinInfo)
  523.     {
  524.     WinInfoPtr curWindow, alertWindow;
  525.  
  526.     curWindow = selWinInfo;
  527.     alertWindow = AskUser((WinInfoPtr) selWinInfo,
  528.         "Please name the new object:", (FuncTyp) NewScreenPlainButton, "");
  529.     SetVar((ObjPtr) alertWindow, OWNERWINDOW, (ObjPtr) curWindow);
  530.     }
  531. }
  532.  
  533. void DoNewScreenShortButton()
  534. /*Makes a new plain button in the current window*/
  535. {
  536.     if (selWinInfo)
  537.     {
  538.     WinInfoPtr curWindow, alertWindow;
  539.  
  540.     curWindow = selWinInfo;
  541.     alertWindow = AskUser((WinInfoPtr) selWinInfo,
  542.         "Please name the new object:", (FuncTyp) NewScreenShortButton, "");
  543.     SetVar((ObjPtr) alertWindow, OWNERWINDOW, (ObjPtr) curWindow);
  544.     }
  545. }
  546.  
  547. void DoNewScreenCheckBox()
  548. /*Makes a new check box in the current window*/
  549. {
  550.     if (selWinInfo)
  551.     {
  552.     WinInfoPtr curWindow, alertWindow;
  553.  
  554.     curWindow = selWinInfo;
  555.     alertWindow = AskUser((WinInfoPtr) selWinInfo,
  556.         "Please name the new object:", (FuncTyp) NewScreenCheckBox, "");
  557.     SetVar((ObjPtr) alertWindow, OWNERWINDOW, (ObjPtr) curWindow);
  558.     }
  559. }
  560.  
  561. void DoNewScreenTextBox()
  562. /*Makes a new text box in the current window*/
  563. {
  564.     if (selWinInfo)
  565.     {
  566.     WinInfoPtr curWindow, alertWindow;
  567.  
  568.     curWindow = selWinInfo;
  569.     alertWindow = AskUser((WinInfoPtr) selWinInfo,
  570.         "Please name the new object:", (FuncTyp) NewScreenTextBox, "");
  571.     SetVar((ObjPtr) alertWindow, OWNERWINDOW, (ObjPtr) curWindow);
  572.     }
  573. }
  574.  
  575. void DoNewScreenEditableTextBox()
  576. /*Makes a new text box in the current window*/
  577. {
  578.     if (selWinInfo)
  579.     {
  580.     WinInfoPtr curWindow, alertWindow;
  581.  
  582.     curWindow = selWinInfo;
  583.     alertWindow = AskUser((WinInfoPtr) selWinInfo,
  584.         "Please name the new object:", (FuncTyp) NewScreenEditableTextBox, "");
  585.     SetVar((ObjPtr) alertWindow, OWNERWINDOW, (ObjPtr) curWindow);
  586.     }
  587. }
  588.  
  589. #endif
  590.  
  591. static ObjPtr DrawObjWindow(theInfo)
  592. WinInfoPtr theInfo;
  593. /*Draws the obj window theInfo*/
  594. {
  595. #ifdef GRAPHICS
  596.     ObjPtr contents;
  597.  
  598.     /*Draw the objects within the window*/
  599.     contents = GetVar((ObjPtr) theInfo, CONTENTS);
  600.     if (contents)
  601.     {
  602.     if (IsList(contents))
  603.     {
  604.         DrawList(contents);
  605.     }
  606.     }
  607. #ifdef GODLIKE
  608.     if (GetPredicate((ObjPtr) theInfo, SHOWBOUNDS))
  609.     {
  610.     DrawBounds(contents);
  611.     }
  612. #endif
  613. #endif
  614.     return ObjTrue;
  615. }
  616.  
  617. #define BIP(r, o)
  618.  
  619. #ifdef PROTO
  620. ObjPtr BoundsInvalid(ObjPtr object, unsigned long changeCount)
  621. #else
  622. ObjPtr BoundsInvalid(object, changeCount)
  623. ObjPtr object;
  624. unsigned long changeCount;
  625. #endif
  626. /*For an object, tests to see if it needs drawing.  Returns
  627.   NULLOBJ    if it does not
  628.   array[4]    giving bounds if it does
  629.   ObjTrue    it it needs to be redrawn but does not know where
  630.  
  631.   In order for an object to be declared invalid, its changed bounds
  632.   must have been changed more recently than changeCount
  633. */
  634. {
  635.     ObjPtr contents;
  636.     ObjPtr myBounds;
  637.     FuncTyp method;
  638.     ObjPtr retVal = NULLOBJ;
  639.  
  640.     method = GetMethod(object, BOUNDSINVALID);
  641.     if (method)
  642.     {
  643.     if (!retVal) retVal = (*method)(object, changeCount);
  644.     if (retVal) invalidFound = true;
  645.     BIP(retVal, object);
  646.     }
  647.  
  648.     MakeVar(object, APPEARANCE);
  649.  
  650.     MakeVar(object, CHANGEDBOUNDS);
  651.     if (GetVarChangeCount(object, CHANGEDBOUNDS) > changeCount)
  652.     {
  653.     /*Object is not good, so return the bounds*/
  654.     myBounds = GetVar(object, CHANGEDBOUNDS);
  655.     if (myBounds && IsArray(myBounds) && RANK(myBounds) == 1
  656.         && DIMS(myBounds)[0] == 4)
  657.     {
  658.         BIP(myBounds, object);
  659.         if (!retVal) retVal = myBounds;
  660.         if (retVal) invalidFound = true;
  661.     }
  662.     else
  663.     {
  664.         BIP(ObjTrue, object);
  665.         if (!retVal) retVal = ObjTrue;
  666.         invalidFound = true;
  667.     }
  668.     }
  669.  
  670.     MakeVar(object, CONTENTS);
  671.     contents = GetVar(object, CONTENTS);
  672.     if (contents && IsList(contents))
  673.     {
  674.     /*Still, maybe some of the contents need to be drawn*/
  675.     Bool firstTime;
  676.     real boundsElements[4];
  677.     real testElements[4];
  678.      ObjPtr test;
  679.      ThingListPtr runner;
  680.     Bool doubleNoBounds = false;
  681.  
  682.     MakeVar(object, BOUNDS);
  683.     myBounds = GetVar(object, BOUNDS);
  684.  
  685.     firstTime = true;
  686.     runner = LISTOF(contents);
  687.     while (runner)
  688.     {
  689.         test = BoundsInvalid(runner -> thing, changeCount);
  690.         if (test)
  691.         {
  692.         /*Hey, the kid needs redrawing*/
  693.         if (IsRealArray(test))
  694.         {
  695.             /*It has a bounds*/
  696.             if (firstTime)
  697.             {
  698.             Array2CArray(boundsElements, test);
  699.             }
  700.             else
  701.             {
  702.             Array2CArray(testElements, test);
  703.             if (testElements[0] < boundsElements[0])
  704.                 boundsElements[0] = testElements[0];
  705.             if (testElements[1] > boundsElements[1])
  706.                 boundsElements[1] = testElements[1];
  707.             if (testElements[2] < boundsElements[2])
  708.                 boundsElements[2] = testElements[2];
  709.             if (testElements[3] > boundsElements[3])
  710.                 boundsElements[3] = testElements[3];
  711.             }
  712.         }
  713.         else
  714.         {
  715.             /*It doesn't have a bounds*/
  716.             if (firstTime)
  717.             {
  718.             /*Try to use my bounds*/
  719.             if (myBounds && IsArray(myBounds) && RANK(myBounds) == 1
  720.                 && DIMS(myBounds)[0] == 4)
  721.             {
  722.                 Array2CArray(boundsElements, myBounds);
  723.             }
  724.             else
  725.             {
  726.                 doubleNoBounds = true;
  727.             }
  728.             }
  729.         }
  730.         firstTime = false;
  731.         }
  732.         runner = runner -> next;
  733.     }
  734.  
  735.     /*Now return the bounds*/
  736.     if (firstTime != true)
  737.     {
  738.         if (doubleNoBounds)
  739.         {
  740.         BIP(ObjTrue, object);
  741.         if (!retVal) retVal = ObjTrue;
  742.         invalidFound = true;
  743.         }
  744.         else
  745.         {
  746.         if (!retVal)
  747.         {
  748.             retVal = NewRealArray(1, 4L);
  749.             CArray2Array(retVal, boundsElements);
  750.             invalidFound = true;
  751.             BIP(retVal, object);
  752.         }
  753.         }
  754.     }
  755.     }
  756.  
  757.     return retVal;
  758. }
  759.  
  760. ObjPtr MakeObjWindowDrawn(curWindow)
  761. WinInfoPtr curWindow;
  762. /*Method to make an obj window drawn.  Returns true iff drawing done*/
  763. {
  764.     ObjPtr boundsInvalid;
  765.     int l, r, b, t;
  766.     int whichBuffer;
  767.  
  768.     if (IsDoubleBuf(curWindow))
  769.     {
  770.     /*Double buffer, determine which buffer we're drawing*/
  771.     ObjPtr var;
  772.  
  773.     var = GetVar((ObjPtr) curWindow, WHICHBUFFER);
  774.     if (var)
  775.     {
  776.         whichBuffer = GetInt(var);
  777.     }
  778.     else
  779.     {
  780.         whichBuffer = 0;
  781.     }
  782.     }
  783.     else
  784.     {
  785.     /*Single buffer, just one buffer*/
  786.     whichBuffer = 0;
  787.     }
  788.  
  789.     invalidFound = false;
  790.     boundsInvalid = BoundsInvalid((ObjPtr) curWindow,
  791.             GetVarChangeCount((ObjPtr) curWindow,
  792.                 whichBuffer ? BUFFER1 : BUFFER0));
  793.     if (boundsInvalid)
  794.     {
  795.     SetVar((ObjPtr) curWindow, whichBuffer ? BUFFER1 : BUFFER0, ObjTrue);
  796.  
  797. #ifndef DONTCLIP
  798.     if ((IsArray(boundsInvalid) && !GetPredicate((ObjPtr) curWindow, SHOWBOUNDS)))
  799.     {
  800.         real elements[4];
  801.         Array2CArray(elements, boundsInvalid);
  802.         SetClipRect((int) elements[0], (int) elements[1], (int) elements[2], (int) elements[3]);
  803.         DrawWindowInfo(curWindow);
  804.         RestoreClipRect();
  805.     }
  806.     else
  807. #endif
  808.     {
  809.         DrawWindowInfo(curWindow);
  810.     }
  811.  
  812.     if (IsDoubleBuf(curWindow))
  813.     {
  814.         swapbuffers();
  815.         /*Set to other buffer*/
  816.         SetVar((ObjPtr) curWindow, WHICHBUFFER, NewInt(whichBuffer ? 0 : 1));
  817.  
  818.     }
  819.     return ObjTrue;
  820.     }
  821.     return ObjFalse;
  822. }
  823.  
  824. ObjPtr PressObjWindow(theInfo, x, y, flags)
  825. WinInfoPtr theInfo;
  826. int x, y;
  827. long flags;
  828. /*Does a press in object window theInfo*/
  829. {
  830.     ObjPtr contents, retVal = ObjFalse;
  831. #ifdef INTERACTIVE
  832.  
  833.     SetDrawingWindow(theInfo);
  834.  
  835.     /*Press in the objects within the window*/
  836.     contents = GetVar((ObjPtr) theInfo, CONTENTS);
  837.     if (contents)
  838.     {
  839.     if (IsList(contents))
  840.     {
  841.         retVal = PressObject(contents, x, y, flags);
  842.     }
  843.     }
  844.     RestoreDrawingWindow();
  845. #endif
  846.     return retVal;
  847. }
  848.  
  849. ObjPtr TurnDialObjWindow(theInfo, whichDial, delta, flags)
  850. WinInfoPtr theInfo;
  851. int whichDial;
  852. real delta;
  853. long flags;
  854. /*Does a turn of a dial whichDial by amount delta in object window theInfo*/
  855. {
  856.     ObjPtr contents, retVal = ObjFalse;
  857. #ifdef INTERACTIVE
  858.  
  859.     SetDrawingWindow(theInfo);
  860.  
  861.     /*Press in the objects within the window*/
  862.     contents = GetVar((ObjPtr) theInfo, CONTENTS);
  863.     if (contents)
  864.     {
  865.     if (IsList(contents))
  866.     {
  867.         retVal = TurnDialObject(contents, whichDial, delta, flags);
  868.     }
  869.     }
  870.     RestoreDrawingWindow();
  871. #endif
  872.     return retVal;
  873. }
  874.  
  875. #ifdef INTERACTIVE
  876. #ifdef PROTO
  877. ObjPtr TurnDialObject(ObjPtr obj, int whichDial, real delta, long flags)
  878. #else
  879. ObjPtr TurnDialObject(obj, whichDial, delta, flags)
  880. ObjPtr obj;
  881. int whichDial;
  882. real delta;
  883. long flags;
  884. #endif
  885. /*Turns dial whichDial amount delta in obj*/
  886. {
  887.     FuncTyp method;
  888.     method = GetMethod(obj, TURNDIAL);
  889.     if (method)
  890.     {
  891.     return (*method)(obj, whichDial, delta, flags);
  892.     }
  893.     else
  894.     {
  895.     return ObjFalse;
  896.     }
  897. }
  898. #endif
  899.  
  900.  
  901. static ObjPtr DropObjWindow(window, object, x, y)
  902. ObjPtr window, object;
  903. int x, y;
  904. /*Does a drop in object window theInfo*/
  905. {
  906.     ObjPtr contents, retVal = ObjFalse;
  907.  
  908.     /*Drop in the objects within the window*/
  909.     contents = GetVar(window, CONTENTS);
  910.     if (contents)
  911.     {
  912.     if (IsList(contents))
  913.     {
  914.         retVal = DropList(contents, object, x, y);
  915.     }
  916.     }
  917.     return retVal;
  918. }
  919.  
  920. static ObjPtr KeyDownObjWindow(theInfo, theKey, flags)
  921. WinInfoPtr theInfo;
  922. int theKey;
  923. long flags;
  924. /*Does a key down in object window theInfo*/
  925. {
  926.     ObjPtr contents;
  927.  
  928.     /*Press in the objects within the window*/
  929.     contents = GetVar((ObjPtr) theInfo, CONTENTS);
  930.     if (contents)
  931.     {
  932.     if (IsList(contents))
  933.     {
  934.         KeyDownList(contents, theKey, flags);
  935.     }
  936.     }
  937.     return ObjTrue;
  938. }
  939.  
  940. void ReshapeObject(object, ol, or, ob, ot, left, right, bottom, top)
  941. ObjPtr object;
  942. int ol, or, ob, ot;
  943. int left, right, bottom, top;
  944. /*Reshapes object, which used to exist within owner with edges ol, or, ob, ot
  945.   to one which exists within owner with edges left, right, bottom, top.*/
  946. {
  947.     FuncTyp method;
  948.     method = GetMethod(object, RESHAPE);
  949.     if (method)
  950.     {
  951.     (*method)(object, ol, or, ob, ot, left, right, bottom, top);
  952.     }
  953.     else
  954.     {
  955.     ObjPtr boundsArray, locArray;
  956.     ObjPtr stickyInt;
  957.     real bounds[4];
  958.     real oldWidth, oldHeight;    /*Old width and height*/
  959.     Bool sideLocked[4];        /*True iff side is locked*/
  960.     Bool xStretch, yStretch;    /*Stretchiness in x and y*/
  961.     int stickiness;            /*Side stickiness of the object*/
  962.     real oldBounds[4];        /*Old bounds of the object*/
  963.     ObjPtr contents;        /*Contents of the object, if any*/
  964.     real wr, hr;            /*Width and height ratios*/
  965.     Bool isIcon = false;        /*Is an icon?*/
  966.  
  967.     wr = ((real) (right - left)) / ((real) (or - ol));
  968.     hr = ((real) (top - bottom)) / ((real) (ot - ob));
  969.  
  970.     boundsArray = GetVar(object, BOUNDS);
  971.     if (!boundsArray || !IsRealArray(boundsArray) || RANK(boundsArray) != 1 ||
  972.         DIMS(boundsArray)[0] != 4)
  973.     {
  974.         /*It might be an icon*/
  975.         locArray = GetVar(object, ICONLOC);
  976.         if (!locArray && !IsRealArray(locArray) || RANK(locArray) != 1 ||
  977.         DIMS(locArray)[0] != 2)
  978.         {
  979.         return;
  980.         }
  981.         isIcon = true;
  982.         Array2CArray(bounds, locArray);
  983.         bounds[3] = bounds[2] = bounds[1];
  984.         bounds[1] = bounds[0];
  985.     }
  986.     else
  987.     {
  988.         Array2CArray(bounds, boundsArray);
  989.     }
  990.     oldBounds[0] = bounds[0];
  991.     oldBounds[1] = bounds[1];
  992.     oldBounds[2] = bounds[2];
  993.     oldBounds[3] = bounds[3];
  994.  
  995.     oldWidth = bounds[1] - bounds[0];
  996.     oldHeight = bounds[3] - bounds[2];
  997.  
  998.     /*Get the object's stickiness*/
  999.     stickyInt = GetVar(object, STICKINESS);
  1000.     if (stickyInt && IsInt(stickyInt))
  1001.     {
  1002.         stickiness = GetInt(stickyInt);
  1003.     }
  1004.     else
  1005.     {
  1006.         stickiness = 0;
  1007.     }
  1008.  
  1009.     if ((stickiness & STICKYLEFT) || (stickiness & FLOATINGLEFT))
  1010.     {
  1011.         if (stickiness & FLOATINGLEFT)
  1012.         {
  1013.         bounds[0] = (bounds[0] - ol) * wr + left;
  1014.         }
  1015.         else
  1016.         {
  1017.         bounds[0] += left - ol;
  1018.         }
  1019.         if (!((stickiness & STICKYRIGHT) || (stickiness & FLOATINGRIGHT)))
  1020.         {
  1021.         bounds[1] = bounds[0] + oldWidth;
  1022.         }
  1023.     }
  1024.     if ((stickiness & STICKYRIGHT) || (stickiness & FLOATINGRIGHT))
  1025.     {
  1026.         if (stickiness & FLOATINGRIGHT)
  1027.         {
  1028.         bounds[1] = (bounds[1] - ol) * wr + left;
  1029.         }
  1030.         else
  1031.         {
  1032.         bounds[1] += right - or;
  1033.         }
  1034.         if (!((stickiness & STICKYLEFT) || (stickiness & FLOATINGLEFT)))
  1035.         {
  1036.         bounds[0] = bounds[1] - oldWidth;
  1037.         }
  1038.     }
  1039.  
  1040.     if ((stickiness & STICKYBOTTOM) || (stickiness & FLOATINGBOTTOM))
  1041.     {
  1042.         if (stickiness & FLOATINGBOTTOM)
  1043.         {
  1044.         bounds[2] = (bounds[2] - ob) * hr + bottom;
  1045.         }
  1046.         else
  1047.         {
  1048.         bounds[2] += bottom - ob;
  1049.         }
  1050.         if (!((stickiness & STICKYTOP) || (stickiness & FLOATINGTOP)))
  1051.         {
  1052.         bounds[3] = bounds[2] + oldHeight;
  1053.         }
  1054.     }
  1055.     if ((stickiness & STICKYTOP) || (stickiness & FLOATINGTOP))
  1056.     {
  1057.         if (stickiness & FLOATINGTOP)
  1058.         {
  1059.         bounds[3] = (bounds[3] - ob) * hr + bottom;
  1060.         }
  1061.         else
  1062.         {
  1063.         bounds[3] += top - ot;
  1064.         }
  1065.         if (!((stickiness & STICKYBOTTOM) || (stickiness & FLOATINGBOTTOM)))
  1066.         {
  1067.         bounds[2] = bounds[3] - oldHeight;
  1068.         }
  1069.     }
  1070.  
  1071.     /*We've got a new bounds, put it back*/
  1072.     if (isIcon)
  1073.     {
  1074.         locArray = NewRealArray(1, 2L);
  1075.         ((real *) ELEMENTS(locArray))[0] = bounds[0];
  1076.         ((real *) ELEMENTS(locArray))[1] = bounds[2];
  1077.         SetVar(object, ICONLOC, locArray);
  1078.     }
  1079.     else
  1080.     {
  1081.         boundsArray = NewRealArray(1, 4L);
  1082.         CArray2Array(boundsArray, bounds);
  1083.         SetVar(object, BOUNDS, boundsArray);
  1084.     }
  1085.  
  1086.     /*If there are some contents to this, do the reshape recursively*/
  1087.     contents = GetVar(object, CONTENTS);
  1088.     if (contents && IsList(contents))
  1089.     {
  1090.         ReshapeList(LISTOF(contents),
  1091.             0, (int) (oldBounds[1] - oldBounds[0]),
  1092.             0, (int) (oldBounds[3] - oldBounds[2]),        0, (int) (bounds[1] - bounds[0]),
  1093.             0, (int) (bounds[3] - bounds[2]));
  1094.     }
  1095.     }
  1096. }
  1097.  
  1098. void ReshapeList(contents, ol, or, ob, ot, left, right, bottom, top)
  1099. ThingListPtr contents;
  1100. int ol, or, ob, ot;
  1101. int left, right, bottom, top;
  1102. /*Reshapes a list of objects using ReshapeObject*/
  1103. {
  1104.     while (contents)
  1105.     {
  1106.     ObjPtr object;
  1107.  
  1108.     object = contents -> thing;
  1109.     ReshapeObject(object, ol, or, ob, ot, left, right, bottom, top);
  1110.         
  1111.     contents = contents -> next;
  1112.     }
  1113. }
  1114.  
  1115. ObjPtr ReshapeObjWindow(window, ol, or, ob, ot, nl, nr, nb, nt)
  1116. ObjPtr window;
  1117. int ol, or, ob, ot;
  1118. int nl, nr, nb, nt;
  1119. /*Reshapes object window given that ol, or, ob, and ot was the old
  1120.   viewport.  Does not redraw anything.*/
  1121. {
  1122.     ObjPtr contents;
  1123.  
  1124.     contents = GetVar(window, CONTENTS);
  1125.     if (contents && IsList(contents))
  1126.     {
  1127.     ReshapeList(LISTOF(contents),
  1128.         0, or - ol, 0, ot - ob,
  1129.         0, nr - nl, 0, nt - nb);
  1130.     }   
  1131.     return ObjTrue;
  1132. }
  1133.  
  1134. void ImInvalid(object)
  1135. ObjPtr object;
  1136. /*Alerts the window system that an object is no longer valid*/
  1137. {
  1138.     FuncTyp method;
  1139.  
  1140.     method = GetMethod(object, IMINVALID);
  1141.     if (method)
  1142.     {
  1143.     (*method)(object);
  1144.     }
  1145.     else
  1146.     {
  1147.     ObjPtr bounds;
  1148.  
  1149.     bounds = GetVar(object, BOUNDS);
  1150.     if (bounds && IsArray(bounds) && RANK(bounds) == 1 &&
  1151.         DIMS(bounds)[0] == 4)
  1152.     {
  1153.         real elements[4];
  1154.         Array2CArray(elements, bounds);
  1155.         /*Kludge because most objects draw one bigger*/
  1156.         elements[1] += 1.0;
  1157.         elements[3] += 1.0;
  1158.         bounds = NewRealArray(1, 4L);
  1159.         CArray2Array(bounds, elements);
  1160.         SetVar(object, CHANGEDBOUNDS, bounds);
  1161.     }
  1162.     else
  1163.     {
  1164.         SetVar(object, CHANGEDBOUNDS, ObjTrue);
  1165.     }
  1166.     }
  1167. }
  1168.  
  1169. void ExpandInvalid(object)
  1170. ObjPtr object;
  1171. /*Expands the invalid bounds*/
  1172. {
  1173.     ObjPtr bounds, changedBounds;
  1174.     real biggerBounds[4];
  1175.     real *elements;
  1176.  
  1177.     changedBounds = GetVar(object, CHANGEDBOUNDS);
  1178.     if (changedBounds && IsArray(changedBounds) && RANK(changedBounds) == 1 &&
  1179.     DIMS(changedBounds)[0] == 4)
  1180.     {
  1181.     /*Have to expand these bounds*/
  1182.     Array2CArray(biggerBounds, changedBounds);
  1183.  
  1184.     bounds = GetVar(object, BOUNDS);
  1185.     if (bounds && IsArray(bounds) && RANK(bounds) == 1 &&
  1186.         DIMS(bounds)[0] == 4)
  1187.     {
  1188.         elements = ELEMENTS(bounds);
  1189.  
  1190.         biggerBounds[0] = MIN(elements[0], biggerBounds[0]);
  1191.         biggerBounds[1] = MAX(elements[1] + 1.0, biggerBounds[1]);
  1192.         biggerBounds[2] = MIN(elements[2], biggerBounds[2]);
  1193.         biggerBounds[3] = MAX(elements[3] + 1.0, biggerBounds[3]);
  1194.  
  1195.         changedBounds = NewRealArray(1, 4L);
  1196.         CArray2Array(changedBounds, biggerBounds);
  1197.         SetVar(object, CHANGEDBOUNDS, changedBounds);
  1198.     }
  1199.     else
  1200.     {
  1201.         SetVar(object, CHANGEDBOUNDS, ObjTrue);
  1202.     }
  1203.     return;
  1204.     }
  1205.  
  1206.     /*Fall through, just do ImInvalid*/
  1207.     ImInvalid(object);
  1208. }
  1209.  
  1210. #ifdef PROTO
  1211. void ImInvalidBounds(ObjPtr object, int l, int r, int b, int t)
  1212. #else
  1213. void ImInvalidBounds(object, l, r, b, t)
  1214. ObjPtr object;
  1215. int l, r, b, t;
  1216. #endif
  1217. /*Alerts the window system that an object is no longer valid
  1218.   within bounds*/
  1219. {
  1220.     ObjPtr bounds;
  1221.     real *elements;
  1222.  
  1223.     bounds = NewRealArray(1, 4L);
  1224.     elements = ELEMENTS(bounds);
  1225.  
  1226.     elements[0] = l;
  1227.     elements[1] = r;
  1228.     elements[2] = b;
  1229.     elements[3] = t;
  1230.  
  1231.     SetVar(object, CHANGEDBOUNDS, bounds);
  1232. }
  1233.  
  1234. #ifdef PROTO
  1235. void PauseDrawing(Bool whether)
  1236. #else
  1237. void PauseDrawing(whether)
  1238. Bool whether;
  1239. #endif
  1240. /*Pauses drawing for a while*/
  1241. {
  1242.     if (whether)
  1243.     {
  1244.     ++pauseDrawing;
  1245.     }
  1246.     else
  1247.     {
  1248.     --pauseDrawing;
  1249.     }
  1250. }
  1251.  
  1252. #ifdef PROTO
  1253. void DrawSkeleton(Bool whether)
  1254. #else
  1255. void DrawSkeleton(whether)
  1256. Bool whether;
  1257. #endif
  1258. /*Does subsequent DrawMe's in skeleton mode or not*/
  1259. {
  1260.     if (!whether)
  1261.     {
  1262.     EraseAll();
  1263.     }
  1264.     OverDraw(whether);
  1265. }
  1266.  
  1267. void DrawMe(object)
  1268. ObjPtr object;
  1269. /*Redraws object in the current window undergoing interaction*/
  1270. {
  1271. #ifdef GRAPHICS
  1272.     ExpandInvalid(object);
  1273.     if (overDraw)
  1274.     {
  1275.         EraseAll();
  1276.         DrawObject(object);
  1277.     }
  1278.     else
  1279.     {
  1280.         if (!pauseDrawing)
  1281.         {
  1282.         drawMouse = true;
  1283.         }
  1284.     }
  1285. #endif
  1286. }
  1287.  
  1288. #ifdef PROTO
  1289. void DrawMeInBounds(ObjPtr object, int l, int r, int b, int t)
  1290. #else
  1291. void DrawMeInBounds(object, l, r, b, t)
  1292. int l, r, b, t;
  1293. ObjPtr object;
  1294. #endif
  1295. /*Redraws object in the current window undergoing interaction*/
  1296. {
  1297. #ifdef GRAPHICS
  1298.     ImInvalidBounds(object, l, r, b, t);
  1299.     if (overDraw)
  1300.     {
  1301.         EraseAll();
  1302.         DrawObject(object);
  1303.     }
  1304.     else
  1305.     {
  1306.         if (!pauseDrawing)
  1307.         {
  1308.         drawMouse = true;
  1309.         }
  1310.     }
  1311. #endif
  1312. }
  1313.  
  1314.  
  1315. void InitPickUp()
  1316. /*Initializes picking up objects*/
  1317. {
  1318.     if (dragBuffer)
  1319.     {
  1320.     DeleteThing(dragBuffer);
  1321.     dragBuffer = NULLOBJ;
  1322.     }
  1323. }
  1324.  
  1325. ObjPtr PickUpObject(object)
  1326. ObjPtr object;
  1327. /*Picks up an object*/
  1328. {
  1329.     object = ObjectWhichRepresents(selWinInfo, object);
  1330.     if (object && IsIcon(object))
  1331.     {
  1332.     if (!dragBuffer)
  1333.     {
  1334.         iconXOff = iconYOff = 0;
  1335.         dragBuffer = NewList();
  1336.         AddToReferenceList(dragBuffer);
  1337.         if (!runningScript)
  1338.         {
  1339.         MySetCursor(ICONCURSOR);
  1340.         }
  1341.     }
  1342.     PostfixList(dragBuffer, object);
  1343.     return ObjTrue;
  1344.     }
  1345.     else
  1346.     {
  1347.     return ObjFalse;
  1348.     }
  1349. }
  1350.  
  1351. void DoPickUpObjects()
  1352. /*Picks up the objects in the icon in the selected window*/
  1353. {
  1354.     DoObjFunction(OF_PICK_UP);
  1355. }
  1356.  
  1357. void ToggleShowBounds()
  1358. /*Toggles the show bounds in the current window*/
  1359. {
  1360.     if (selWinInfo)
  1361.     {
  1362.     Bool lastState;
  1363.     lastState = GetPredicate((ObjPtr) selWinInfo, SHOWBOUNDS);
  1364.     SetVar((ObjPtr) selWinInfo, SHOWBOUNDS,
  1365.             lastState ? ObjFalse : ObjTrue);
  1366. #ifdef GRAPHICS
  1367. #ifdef WINDOWS4D
  1368.     if (lastState)
  1369.     {
  1370.         int l, r, b, t;
  1371.  
  1372.         GetWindowBounds(&l, &r, &b, &t);
  1373.         minsize(r - l + 1, t - b + 1);
  1374.         maxsize(r - l + 1, t - b + 1);
  1375.         winconstraints();
  1376.     }
  1377.     else
  1378.     {
  1379.         minsize(40, 30);
  1380.         maxsize(1280, 1024);
  1381.         winconstraints();
  1382.     }
  1383. #endif
  1384. #endif
  1385.     ImInvalid((ObjPtr) selWinInfo);
  1386.     }
  1387. }
  1388.  
  1389. #ifdef PROTO
  1390. WinInfoPtr NewObjWindow(ObjPtr superClass,
  1391.     char *title, long flags,
  1392.     int minWidth, int minHeight, int maxWidth, int maxHeight)
  1393. #else
  1394. WinInfoPtr NewObjWindow(superClass, title, flags, minWidth, minHeight, maxWidth, maxHeight)
  1395. ObjPtr superClass;
  1396. char *title;
  1397. long flags;
  1398. int minWidth, minHeight, maxWidth, maxHeight;
  1399. #endif
  1400. /*Creates a new object window for repObj with title title and flags flags.
  1401.   repObj can be null.  If it isn't, the title will be updated according to 
  1402.   the repObj's NAME.  superClass is
  1403.   the class of the window, if NULLOBJ objWindowClass will be used*/
  1404. {
  1405.     WinInfoPtr retVal;
  1406.     WindowID theWindow;
  1407.  
  1408.     /*Edit flags*/
  1409.     if (!hasRGB && (flags & WINRGB))
  1410.     {
  1411.     flags &= ~WINRGB;
  1412.     }
  1413.     if (!hasCmap) flags |= WINRGB;
  1414.  
  1415.     if (showWindows)
  1416.     {
  1417.     theWindow = NewOpenedWindow(title, minWidth, minHeight, maxWidth, maxHeight,flags);
  1418.     }
  1419.     else
  1420.     {
  1421.     theWindow = 0;
  1422.     }
  1423.  
  1424.     retVal = NewWinInfo(superClass ? superClass : objWindowClass, theWindow, 
  1425.         flags, title,  minWidth, minHeight, maxWidth, maxHeight);
  1426.     SetVar((ObjPtr) retVal, CONTENTS, NewList());    /*Contents*/
  1427.     if (showWindows)
  1428.     {
  1429.     CEWS(retVal, minWidth, minHeight);
  1430.     }
  1431.  
  1432. #ifdef SELNEWWINDOWS
  1433.     inputWindow = retVal;
  1434. #endif
  1435.  
  1436.     return retVal;
  1437. }
  1438.  
  1439. static ObjPtr FindObjectObjClass(object, name)
  1440. ObjPtr object;
  1441. char *name;
  1442. /*Searches an object and its contents for an object with name*/
  1443. {
  1444.     ObjPtr retVal = NULLOBJ;
  1445.     ObjPtr objName, contents;
  1446.  
  1447.     /*First check to see if I am the object*/
  1448.     objName = GetVar(object, NAME);
  1449.     if (objName && IsString(objName) && ObjectNameMatches(name, GetString(objName)))
  1450.     {
  1451.     if (!retVal)
  1452.     {
  1453.         retVal = NewList();
  1454.     }
  1455.     PostfixList(retVal, object);
  1456.     }
  1457.  
  1458.     /*Now check my CONTENTS*/
  1459.     contents = GetVar(object, CONTENTS);
  1460.     if (contents)
  1461.     {
  1462.     ObjPtr foundObjects;
  1463.     foundObjects = FindNamedObject(contents, name);
  1464.     if (foundObjects)
  1465.     {
  1466.         if (!retVal)
  1467.         {
  1468.         retVal = NewList();
  1469.         }
  1470.         AppendList(retVal, foundObjects);
  1471.     }
  1472.     }
  1473.  
  1474.     return retVal;
  1475. }
  1476.  
  1477. static ObjPtr FindObjectObjWindow(object, name)
  1478. ObjPtr object;
  1479. char *name;
  1480. /*Searches an object window and its subwindows for object name*/
  1481. {
  1482.     ObjPtr subWindows;
  1483.     ObjPtr retVal;
  1484.     ObjPtr foundObjects;
  1485.  
  1486.     retVal = NULLOBJ;
  1487.  
  1488.     foundObjects = FindObjectObjClass(object, name);
  1489.     if (foundObjects)
  1490.     {
  1491.     if (!retVal)
  1492.     {
  1493.         retVal = NewList();
  1494.     }
  1495.     AppendList(retVal, foundObjects);
  1496.     }
  1497.  
  1498.     subWindows = GetVar(object, SUBWINDOWS);
  1499.     if (subWindows)
  1500.     {
  1501.     foundObjects = FindNamedObject(subWindows, name);
  1502.     if (foundObjects)
  1503.     {
  1504.         if (!retVal)
  1505.         {
  1506.         retVal = NewList();
  1507.         }
  1508.         AppendList(retVal, foundObjects);
  1509.     }
  1510.     }
  1511.     return retVal;
  1512. }
  1513.  
  1514. static ObjPtr ForAllObjectsObjClass(object, routine)
  1515. ObjPtr object;
  1516. FuncTyp routine;
  1517. /*Does routine on all objects within object*/
  1518. {
  1519.     ObjPtr contents;
  1520.  
  1521.     (*routine)(object);
  1522.  
  1523.     /*Now check my CONTENTS*/
  1524.     contents = GetVar(object, CONTENTS);
  1525.     if (contents)
  1526.     {
  1527.     ForAllObjects(contents, routine);
  1528.     }
  1529.  
  1530.     return ObjTrue;
  1531. }
  1532.  
  1533. extern ObjPtr objClass;
  1534.  
  1535. ObjPtr ShowObjWindowFrame(curWindow)
  1536. WinInfoPtr curWindow;
  1537. /*Shows the window frame*/
  1538. {
  1539. #ifdef GRAPHICS
  1540. #ifdef WINDOWS4D
  1541. #ifndef NOHIDEFRAME
  1542.     if (!(selWinInfo -> id))
  1543.     {
  1544.     return ObjFalse;
  1545.     }
  1546.  
  1547.     SelWindow(curWindow);
  1548.     if (logging)
  1549.     {
  1550.     Log("show frame\n");
  1551.     }
  1552.     wintitle(selWinInfo -> winTitle);
  1553.     minsize(selWinInfo -> minWidth, selWinInfo -> minHeight);
  1554.     maxsize(selWinInfo -> maxWidth, selWinInfo -> maxHeight);
  1555.     winconstraints();
  1556.     selWinInfo -> flags &= ~WINNOFRAME;
  1557. #endif
  1558. #endif
  1559. #endif
  1560.     return ObjTrue;
  1561. }
  1562.  
  1563. ObjPtr HideObjWindowFrame(curWindow)
  1564. WinInfoPtr curWindow;
  1565. /*Hides the window frame*/
  1566. {
  1567. #ifdef WINDOWS4D
  1568. #ifdef GRAPHICS
  1569. #ifndef NOHIDEFRAME
  1570.     if (logging)
  1571.     {
  1572.     Log("hide frame\n");
  1573.     }
  1574.  
  1575.     SelWindow(curWindow);
  1576.     if (!(selWinInfo -> id))
  1577.     {
  1578.     return ObjFalse;
  1579.     }
  1580.     noborder();
  1581.     minsize(selWinInfo -> minWidth, selWinInfo -> minHeight);
  1582.     maxsize(selWinInfo -> maxWidth, selWinInfo -> maxHeight);
  1583.     winconstraints();
  1584.     selWinInfo -> flags |= WINNOFRAME;
  1585. #endif
  1586. #endif
  1587. #endif
  1588.     return ObjTrue;
  1589. }
  1590.  
  1591. void InitObjWindows()
  1592. /*Initializes the obj window system*/
  1593. {
  1594.     objWindowClass = NewObject(windowClass, 0);
  1595.     AddToReferenceList(objWindowClass);
  1596.     SetMethod(objWindowClass, CLOSE, CloseObjWindow);
  1597.     SetMethod(objWindowClass, DRAW, DrawObjWindow);
  1598.     SetMethod(objWindowClass, PRESS, PressObjWindow);
  1599.     SetMethod(objWindowClass, TURNDIAL, TurnDialObjWindow);
  1600.     SetMethod(objWindowClass, DROPOBJECTS, DropObjWindow);
  1601.     SetMethod(objWindowClass, KEYDOWN, KeyDownObjWindow);
  1602.     SetMethod(objWindowClass, RESHAPE, ReshapeObjWindow);
  1603.     SetMethod(objWindowClass, MAKEDRAWN, MakeObjWindowDrawn);
  1604.     SetMethod(objWindowClass, SHOWFRAME, ShowObjWindowFrame);
  1605.     SetMethod(objWindowClass, HIDEFRAME, HideObjWindowFrame);
  1606.     SetMethod(objWindowClass, FINDOBJECT, FindObjectObjWindow);
  1607.  
  1608.     /*KLUDGE*/
  1609.     SetMethod(objClass, FINDOBJECT, FindObjectObjClass);
  1610.     SetMethod(objClass, FORALLOBJECTS, ForAllObjectsObjClass);
  1611. }
  1612.  
  1613. static Bool repped;
  1614. static ObjPtr testObject;
  1615. static ObjPtr objectWhichRepresents;
  1616.  
  1617. static ObjPtr CheckRepObj(object)
  1618. ObjPtr object;
  1619. /*Checks if an object matches testObject*/
  1620. {
  1621.     if (IsIcon(object) && (GetVar(object, REPOBJ) == testObject))
  1622.     {
  1623.     objectWhichRepresents = object;
  1624.     repped = true;
  1625.     return ObjTrue;
  1626.     }
  1627.     else if ((object == testObject) && !repped)
  1628.     {
  1629.     objectWhichRepresents = object;
  1630.     return ObjTrue;
  1631.     }
  1632.     else
  1633.     {
  1634.     return ObjFalse;
  1635.     }
  1636. }
  1637.  
  1638. ObjPtr ObjectWhichRepresents(window, object)
  1639. WinInfoPtr window;
  1640. ObjPtr object;
  1641. /*Returns the object in window that represents object, or NULLOBJ*/
  1642. {
  1643.     if (object == (ObjPtr) window) return (ObjPtr) window;
  1644.  
  1645.     repped = false;
  1646.     objectWhichRepresents = NULLOBJ;
  1647.     testObject = object;
  1648.  
  1649.     if (object)
  1650.     {
  1651.     ForAllObjects((ObjPtr) window, CheckRepObj);
  1652.     }
  1653.     else
  1654.     {
  1655.     return NULLOBJ;
  1656.     }
  1657.     if (!objectWhichRepresents)
  1658.     {
  1659.     ObjPtr var;
  1660.     var = GetVar(object, NAME);
  1661.     if (var)
  1662.     {
  1663.         ObjPtr list;
  1664.         list = FindNamedObject((ObjPtr) window, GetString(var));
  1665.         if (list && LISTOF(list))
  1666.         {
  1667.         objectWhichRepresents = LISTOF(list) -> thing;
  1668.         }
  1669.     }
  1670.     }
  1671.     return objectWhichRepresents;
  1672. }
  1673.  
  1674. ObjPtr DeleteObject(object)
  1675. ObjPtr object;
  1676. /*Deletes an object from the current window.*/
  1677. {
  1678.     ObjPtr deleteObject;
  1679.  
  1680.     if (!selWinInfo || !object) return ObjFalse;
  1681.     deleteObject = ObjectWhichRepresents(selWinInfo, object);
  1682.     Select(object, false);
  1683.     if (deleteObject)
  1684.     {
  1685.     FuncTyp method;
  1686.     object = deleteObject;
  1687.     method = GetMethod(object, DELETEICON);
  1688.  
  1689.     if (method)
  1690.     {
  1691.         if (IsTrue((*method)(object)))
  1692.         {
  1693.         ObjPtr contentsList;
  1694.         contentsList = GetVar(object, PARENT);
  1695.          if (!contentsList || !IsList(contentsList))
  1696.         {
  1697.             contentsList = GetVar(contentsList, CONTENTS);
  1698.         }
  1699.         if (contentsList && IsList(contentsList))
  1700.         {
  1701.             ObjPtr parent;
  1702.             parent = GetVar(contentsList, PARENT);
  1703.             if (parent)
  1704.             {
  1705.             ImInvalid(parent);
  1706.             }
  1707.             DeleteFromList(contentsList, object);
  1708.             return ObjTrue;
  1709.         }
  1710.         else
  1711.         {
  1712.             ReportError("DeleteObject","Internal error: cannot find contents list");
  1713.         }
  1714.         }
  1715.     }
  1716.     }
  1717.     return ObjFalse;
  1718. }
  1719.  
  1720. void DoDelete()
  1721. /*Deletes objects*/
  1722. {
  1723.     ObjPtr corral;
  1724.     Bool didit = false;
  1725.  
  1726.     if (logging)
  1727.     {
  1728.     InhibitLogging(true);
  1729.     }
  1730.     if (selWinInfo)
  1731.     {
  1732.     ForAllSelectedObjects(DeleteObject);
  1733.     }
  1734.     if (logging)
  1735.     {
  1736.     InhibitLogging(false);
  1737.     if (didit)
  1738.     {
  1739.         Log("delete\n");
  1740.     }
  1741.     }
  1742. }
  1743.  
  1744. void KillObjWindows()
  1745. /*Kills the obj window system*/
  1746. {
  1747.     DeleteThing(objWindowClass);
  1748. }
  1749.  
  1750. ObjPtr FindNamedObject(object, name)
  1751. ObjPtr object;
  1752. char *name;
  1753. /*Finds object with name within object.  Returns a list of matching objects*/
  1754. {
  1755.     FuncTyp method;
  1756.     ObjPtr retVal;
  1757.  
  1758.     method = GetMethod(object, FINDOBJECT);
  1759.     if (method)
  1760.     {
  1761.     retVal = (*method)(object, name);
  1762.     {
  1763.         ThingListPtr runner;
  1764.         if (retVal)
  1765.         {
  1766.         ObjPtr test, temp;
  1767.         ObjPtr repObj = NULLOBJ;
  1768.         Bool hasExact, hasInexact;
  1769.         ObjPtr exactList;
  1770.  
  1771.         /*See if there are both exact and inexact matches*/
  1772.         hasExact = false;
  1773.         hasInexact = false;
  1774.         runner = LISTOF(retVal);
  1775.         exactList = NULLOBJ;
  1776.         while (runner)
  1777.         {
  1778.             test = runner -> thing;
  1779.             temp = GetVar(test, NAME);
  1780.             if (0 == strcmp2(GetString(temp), name))
  1781.             {
  1782.             if (!hasExact)
  1783.             {
  1784.                 exactList = NewList();
  1785.             }
  1786.             PrefixList(exactList, test);
  1787.             hasExact = true;
  1788.             }
  1789.             else
  1790.             {
  1791.             hasInexact = true;
  1792.             }
  1793.             runner = runner -> next;
  1794.         }
  1795.         if (hasExact && hasInexact)
  1796.         {
  1797.             /*Only use the exact matches*/
  1798.             retVal = exactList;
  1799.         }
  1800.  
  1801.         /*See if multiple objects are really the same object*/
  1802.         runner = LISTOF(retVal);
  1803.         while (runner)
  1804.         {
  1805.             test = runner -> thing;
  1806.             if (IsIcon(test) && (temp = GetVar(test, REPOBJ)))
  1807.             {
  1808.             test = temp;
  1809.             }
  1810.             
  1811.             if (repObj)
  1812.             {
  1813.             /*There's already a repobj*/
  1814.             if (test != repObj) break;
  1815.             }
  1816.             else
  1817.             {
  1818.             /*There isn't a repobj yet*/
  1819.             repObj = test;
  1820.             }
  1821.             runner = runner -> next;
  1822.         }
  1823.         if (!runner)
  1824.         {
  1825.             /*They are all the same object*/
  1826.             retVal = NewList();
  1827.             PrefixList(retVal, repObj);
  1828.         }
  1829.         }
  1830.         return retVal;
  1831.     }
  1832.     }
  1833.     else
  1834.     {
  1835.     return NULLOBJ;
  1836.     }
  1837. }
  1838.  
  1839. void MakeMeCurrent(object)
  1840. ObjPtr object;
  1841. /*Makes object the current object in the local window*/
  1842. {
  1843.     if (runningScript && !scriptSelectP)
  1844.     {
  1845.     return;
  1846.     }
  1847.  
  1848.     if (selWinInfo)
  1849.     {
  1850.     ObjPtr oldCurrent;
  1851.  
  1852.     oldCurrent = GetVar((ObjPtr) selWinInfo, CURRENT);
  1853.         if (oldCurrent == object) return;
  1854.     FlushKeystrokes();
  1855.     SetVar((ObjPtr) selWinInfo, CURRENT, object);
  1856.     if (oldCurrent)
  1857.     {
  1858.         ImInvalid(oldCurrent);
  1859.         DeferMessage(oldCurrent, YOURENOTCURRENT);
  1860.     }
  1861.     if (object) ImInvalid(object);
  1862.     }
  1863. }
  1864.  
  1865. Bool AmICurrent(object)
  1866. ObjPtr object;
  1867. /*Returns true iff object is the current object in the current window*/
  1868. {
  1869.     if (selWinInfo)
  1870.     {
  1871.     return GetVar((ObjPtr) selWinInfo, CURRENT) == object ? true : false;
  1872.     }
  1873.     else
  1874.     {
  1875.     return false;
  1876.     }
  1877. }
  1878.